<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"/>
<title>本地化字符串</title><link href="../zdoc.css" rel="stylesheet" type="text/css"/><link href="../_rs/site.css" rel="stylesheet" type="text/css"/><script src="../_rs/jquery.js" language="Javascript"></script><script src="../_rs/site.js" language="Javascript"></script><script src="../_rs/z.js" language="Javascript"></script>
</head>
<body><a name="top"></a>
<div class="zdoc_header">本地化字符串</div>
<div class="zdoc_author"><em>By:</em><b>zozoh</b><a href="mailto:zozohtnt@gmail.com">&lt;zozohtnt@gmail.com&gt;</a></div>
<div class="zdoc_body">
<ul class="zdoc_index_table">
<li>
<div><span class="num">1</span><a href="#基本策略">基本策略</a></div>
</li>
<li>
<div class="zdoc_folder"><span class="num">2</span><a href="#使用字符串">使用字符串</a></div>
<ul>
<li>
<div><span class="num">2.1</span><a href="#在主模块上声明">在主模块上声明</a></div>
</li>
<li>
<div><span class="num">2.2</span><a href="#在_JSP_里使用">在 JSP 里使用</a></div>
</li>
<li>
<div><span class="num">2.3</span><a href="#我到底支持哪些语言">我到底支持哪些语言</a></div>
</li>
</ul>
</li>
<li>
<div><span class="num">3</span><a href="#切换本地语言">切换本地语言</a></div>
</li>
<li>
<div><span class="num">4</span><a href="#设置应用程序的默认语言">设置应用程序的默认语言</a></div>
</li>
<li>
<div><span class="num">5</span><a href="#使用过滤器">使用过滤器</a></div>
</li>
<li>
<div><span class="num">6</span><a href="#定制自己的本地化字符串方式">定制自己的本地化字符串方式</a></div>
</li>
<li>
<div><span class="num">7</span><a href="#让_Ioc_容器管理你的_MessageLoader">让 Ioc 容器管理你的 MessageLoader</a></div>
</li>
</ul>
<div class="hr"><b></b></div>
<h1><a name="基本策略"></a>基本策略</h1>
<div style="float:right;"><a href="#top">Top</a></div>
<p>每个 Mvc 框架都有自己的本地化字符串的解决方案， Nutz.Mvc 的这个是相当简陋的。我只是个人觉得足够用了。下面我把它简单介绍一下：</p>
<ul type="disc">
<li>假定所有的本地化字符串文件都会存放在某一目录下
<ul type="circle">
<li>这个目录下所有的 .properties 文件，将作为默认的本地字符串文件。</li>
<li>每一种语言都会是一个目录，目录名称对应一个 Locale 的 toString()，请参看 java.util.Locale 的 JDoc
<ul type="square">
<li>比如简体中文，就是 zh_CN</li>
<li>比如美式英语，就是 en_US</li>
</ul>
</li>
<li>目录下所有的 .properties 文件存放着该地区的字符串信息</li>
<li> .properties 文件需要按照 UTF-8 方式编码</li>
</ul>
</li>
<li>目录，通过 @Localization("全路径") 声明在主模块上</li>
<li>当应用启动时，一次读入所有的字符串，并存入 ServletContext，属性名称为：“org.nutz.mvc.annotation.Localization”</li>
<li>应用可以自行设置当前 Session 是哪一个国家和地区
<ul type="circle">
<li>Mvcs.setLocaleName(String localeName)</li>
</ul>
</li>
<li>每次请求时，会根据 Session 中的 localeName，从 ServletContext 中将对应 Locale 的字符串取出，设入 Request 对象
<ul type="circle">
<li>属性名为 "msg"</li>
<li>如果当前会话没有被设置 Locale，则将 "msg" 设置成默认本地化字符串</li>
</ul>
</li>
</ul>
<div class="hr"><b></b></div>
<h1><a name="使用字符串"></a>使用字符串</h1>
<div style="float:right;"><a href="#top">Top</a></div>
<h2><a name="在主模块上声明"></a>在主模块上声明</h2>
<div style="float:right;"><a href="#top">Top</a></div>
<p>比如：</p>
<pre>...
@Localization("mymsg")
public class MyMainModule {
	...
</pre>
<ul type="disc">
<li>在主模块上声明 @Localization 注解，指向一个目录</li>
<li>在目录下建立文件夹，比如 <b>zh_CN</b>，每个目录下所有 <b> .properties</b> 文件都会被当作字符串文件</li>
<li><b> .properties</b> 文件 一定要是 UTF-8 编码的</li>
<li>比如 @Locallization("mymsg") 会指向 CLASSPATH 下的 <b>mymsg</b> 目录</li>
</ul>
<h2><a name="在_JSP_里使用"></a>在 JSP 里使用</h2>
<div style="float:right;"><a href="#top">Top</a></div>
<p><b>直接 Scriptlet</b></p>
<pre>...
&lt;h1&gt;&lt;%=((Map&lt;String,String&gt;)request.getAttribute("msg")).get("my.msg.key")%&gt;&lt;/h1&gt;
...
</pre>
<p><b>采用 JSTL</b></p>
<pre>...
&lt;h1&gt;${msg['my.msg.key']}&lt;/h1&gt;
...
</pre>
<p></p>
<h2><a name="我到底支持哪些语言"></a>我到底支持哪些语言</h2>
<div style="float:right;"><a href="#top">Top</a></div>
<p>请参看 <b>org.nutz.mvc.Mvcs</b> 的 JavaDoc，这里我列几个常用的方法:</p>
<table border="1" cellspacing="2" cellpadding="4">
<tr>
<td> Mvcs.getLocalizationKey()                </td>
<td> 获取当前会话的 Locale 名称 </td>
</tr>
<tr>
<td> Mvcs.setLocalizationKey(String key)      </td>
<td> 为当前会话设置 Locale 的名称 </td>
</tr>
<tr>
<td> Mvcs.getLocalizationKeySet()             </td>
<td> 获取整个应用可用的 Locale 名称集合 </td>
</tr>
</table>
<div class="hr"><b></b></div>
<h1><a name="切换本地语言"></a>切换本地语言</h1>
<div style="float:right;"><a href="#top">Top</a></div>
<p>自从 1.b.44 之后，Nutz 对本地字符串语言切换的接口做了改动:</p>
<pre>// 设置一个本地字符串
@At("/lang/change")
@Ok("redirect:/")
public void changeLocal( @Param("lang") String lang){
    Mvcs.setLocalizationKey(lang);
}
</pre>
<p>1.b.44 版本 之前，只能采用如下方法:</p>
<pre>// 设置一个本地字符串
@At("/lang/change")
@Ok("redirect:/")
public void changeLocal( @Param("lang") String lang, HttpSession sess){
    Mvcs.setLocale(sess, lang);
    Mvcs.setLocaleName(sess, lang);
}
</pre>
<p></p>
<div class="hr"><b></b></div>
<h1><a name="设置应用程序的默认语言"></a>设置应用程序的默认语言</h1>
<div style="float:right;"><a href="#top">Top</a></div>
<p>对于任何一个支持多语言版本的应用程序，第一次启动的时候，总要采用一种语言。自 1.b.44 之后，Nutz 给出了一个明确的方法，来设置这个信息。你可以在应用程序启动的Setup 时，调用:</p>
<pre>...
Mvcs.setDefaultLocalizationKey("zh_CN");
...
</pre>
<p>在 1.b.45 后，Nutz 又给出一个更直接的实现，你可以直接:</p>
<pre>...
@Localization(value="mymsg", defaultLocalizationKey="zh_CN")
public class MyMainModule {
...
</pre>
<p></p>
<div class="hr"><b></b></div>
<h1><a name="使用过滤器"></a>使用过滤器</h1>
<div style="float:right;"><a href="#top">Top</a></div>
<p>有些是由，你想让你的 JSP 文件 (不是通过 Nutz.Mvc 入口函数访问的)也可以使用"<b>本地化字符串</b>"功能，那么你需要在 web.xml 这么配置:</p>
<pre>&lt;!--
	Nutz.Mvc 还提供了一个过滤器，你可以用这个过滤器为所有的直接访问的 jsp 设置必要的 Request 属性。 比如 ${base}
	以及 ${msg}
--&gt;
&lt;filter&gt;
	&lt;filter-name&gt;msgs&lt;/filter-name&gt;
	&lt;filter-class&gt;org.nutz.mvc.NutFilter&lt;/filter-class&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
	&lt;filter-name&gt;msgs&lt;/filter-name&gt;
	&lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;

&lt;filter-mapping&gt;
	&lt;filter-name&gt;msgs&lt;/filter-name&gt;
	&lt;url-pattern&gt;*.jspx&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</pre>
<p></p>
<div class="hr"><b></b></div>
<h1><a name="定制自己的本地化字符串方式"></a>定制自己的本地化字符串方式</h1>
<div style="float:right;"><a href="#top">Top</a></div>
<p>你需要自己实现一个 MessageLoader 的接口，然后声明到 '@Localization' 中。比如你的实现类名字为 'MyMessageLoader'，那么你应该这么声明:</p>
<pre>...
@Localization( type=MyMessageLoader.class,
               value="msg" )
public class MyMainModule {
...
</pre>
<p>对于 MessageLoader 接口，就一个方法需要你来实现:</p>
<pre>public interface MessageLoader {
    /**
     * 本函数将根据传入的 "refer" 参数，返回一个 Map &lt;br&gt;
     * Map 的键是语言的名称，比如 "en_US", "zh_CN" 等，&lt;br&gt;
     * 你会通过 Mvcs.setLocalizationKey 来直接使用这个键值
     * &lt;p&gt;
     * 与键对应的是一个消息字符串的 Map, 该 Map 的键就是消息键，值就是消息内容
     * 
     * @param refer
     *            参考值。来自 '@Localization.value'
     * @return 多国语言字符串的 Map
     */
    Map&lt;String, Map&lt;String, Object&gt;&gt; load(String refer);
}
</pre>
<p>你声明在 '@Localization' 中的 "value" 的值，会被传入这个接口，作为 refer 参数的值</p>
<div class="hr"><b></b></div>
<h1><a name="让_Ioc_容器管理你的_MessageLoader"></a>让 Ioc 容器管理你的 MessageLoader</h1>
<div style="float:right;"><a href="#top">Top</a></div>
<p>这是 1.b.45 已后才有的方法:</p>
<pre>...
@Localization( type=MyMessageLoader.class,
               beanName="myMessages", 
               value="msg" )
public class MyMainModule {
...
</pre>
<p>提供了 "beanName" 属性，这样，Nutz.Mvc 将从 Ioc 容器中加载名字为 "myMessages" 的对象。当然它的类型必须是你声明的 "MyMessageLoader.class" </p>
</div>
<div class="zdoc_footer"><em>By:</em><b>zozoh</b><a href="mailto:zozohtnt@gmail.com">&lt;zozohtnt@gmail.com&gt;</a></div>
</body>
</html>